/**
 * @file debug_images.c
 * @brief 调试模式下的图像保存和标注功能实现
 * @version 1.0
 * @date 2023-05-20
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <errno.h>

#include "debug_images.h"
#include "image_saver.h"
#include "system_utils.h"
#include "visual_monitor.h"
#include "stereo_monitor.h"
#include "uart_protocol.h"
#include "common_defs.h"

/**
 * @brief 确保目录存在，如果不存在则创建
 * 
 * @param directory 目录路径
 * @return int 成功返回0，失败返回-1
 */
static int ensure_directory_exists(const char *directory) {
    if (!directory || !*directory) {
        log_message(LOG_LEVEL_ERROR, "无效的目录路径（空）");
        return -1;
    }
    
    log_message(LOG_LEVEL_DEBUG, "检查目录是否存在: %s", directory);
    
    struct stat st = {0};
    
    // 检查目录是否存在
    if (stat(directory, &st) == -1) {
        // 目录不存在，创建它
        log_message(LOG_LEVEL_INFO, "目录不存在，尝试创建: %s", directory);
        
#ifdef _WIN32
        // Windows平台使用 _mkdir
        if (_mkdir(directory) != 0) {
            log_message(LOG_LEVEL_ERROR, "无法创建目录 %s: %s", directory, strerror(errno));
            return -1;
        }
#else
        // Linux/Unix平台使用 mkdir
        int res = mkdir(directory, 0755);
        if (res != 0) {
            log_message(LOG_LEVEL_ERROR, "无法创建目录 %s: %s (错误码: %d)", 
                       directory, strerror(errno), errno);
            return -1;
        }
#endif
        log_message(LOG_LEVEL_INFO, "已成功创建目录: %s", directory);
    } else {
        // 检查是否是目录
        if (!S_ISDIR(st.st_mode)) {
            log_message(LOG_LEVEL_ERROR, "路径存在但不是目录: %s", directory);
            return -1;
        }
        log_message(LOG_LEVEL_DEBUG, "目录已存在: %s", directory);
    }
    
    return 0;
}

/**
 * @brief 在图像上添加传感器数据标注
 * 
 * @param image 图像数据
 * @param width 图像宽度
 * @param height 图像高度
 * @param channels 图像通道数
 * @param sensor_data 传感器数据包
 * @param timestamp 时间戳
 * @return int 成功返回0，失败返回-1
 */
static int annotate_image(unsigned char *image, int width, int height, int channels,
                          const SensorDataPacket *sensor_data, uint64_t timestamp) {
#ifdef HAVE_OPENCV
    // 使用OpenCV绘制文本
    // 获取当前系统时间
    time_t time_sec = timestamp / 1000;
    struct tm tm_info;
    
#ifdef _WIN32
    localtime_s(&tm_info, &time_sec);
#else
    localtime_r(&time_sec, &tm_info);
#endif
    
    char time_str[32];
    strftime(time_str, sizeof(time_str), "%Y-%m-%d %H:%M:%S", &tm_info);
    
    // 调用OpenCV函数添加时间戳和传感器数据信息
    opencv_annotate_image(
        image, width, height, channels,
        time_str,
        sensor_data ? sensor_data->temperature : 0.0f,
        sensor_data ? sensor_data->humidity : 0.0f,
        sensor_data ? sensor_data->wind_speed : 0.0f,
        sensor_data ? sensor_data->wind_direction : 0.0f,
        sensor_data ? sensor_data->tension1 : 0.0f,
        sensor_data ? sensor_data->tension2 : 0.0f
    );
    
    return 0;
#else
    log_message(LOG_LEVEL_WARNING, "未启用OpenCV支持，无法在图像上添加标注");
    return -1;
#endif
}

/**
 * @brief 生成格式化的时间字符串，用于文件名
 * 
 * @param timestamp 时间戳（毫秒）
 * @param buffer 输出缓冲区
 * @param buffer_size 缓冲区大小
 */
static void format_time_for_filename(uint64_t timestamp, char *buffer, size_t buffer_size) {
    time_t time_sec = timestamp / 1000;
    struct tm tm_info;
    
#ifdef _WIN32
    localtime_s(&tm_info, &time_sec);
#else
    localtime_r(&time_sec, &tm_info);
#endif
    
    // 格式化为yyyymmdd_hhmmss
    strftime(buffer, buffer_size, "%Y%m%d_%H%M%S", &tm_info);
}

/**
 * @brief 保存调试图像
 * 
 * @param visual_data 视觉数据，可为NULL
 * @param stereo_data 立体视觉数据，可为NULL
 * @param sensor_data 传感器数据，可为NULL
 * @param save_dir 数据目录（忽略，使用picture_docu）
 * @param timestamp 时间戳
 * @return int 成功返回0，失败返回非0
 */
int save_debug_images(const VisualIceData *visual_data, 
                     const StereoData *stereo_data,
                     const SensorDataPacket *sensor_data,
                     const char *save_dir, 
                     uint64_t timestamp) {
    int success_count = 0;
    char filename[MAX_PATH_LENGTH];
    char time_str[32];
    
    // 使用指定的picture_docu目录
    const char *picture_dir = "picture_docu";
    
    // 记录调试信息
    log_message(LOG_LEVEL_INFO, "尝试保存调试图像到目录: %s", picture_dir);
    log_message(LOG_LEVEL_INFO, "视觉数据状态: %s, 立体视觉数据状态: %s", 
              (visual_data && visual_data->latest_frame.data) ? "有效" : "无效",
              (stereo_data && stereo_data->left_frame.data) ? "有效" : "无效");
    
    // 确保目录存在
    if (ensure_directory_exists(picture_dir) != 0) {
        log_message(LOG_LEVEL_ERROR, "无法创建图像保存目录: %s", picture_dir);
        return -1;
    } else {
        log_message(LOG_LEVEL_INFO, "已确认或创建图像保存目录: %s", picture_dir);
    }
    
    // 格式化时间字符串用于文件名
    format_time_for_filename(timestamp, time_str, sizeof(time_str));
    
    // 保存400W摄像头图像
    if (visual_data && visual_data->latest_frame.data) {
        // 复制图像数据用于添加标注
        unsigned char *annotated_image = (unsigned char*)malloc(
            visual_data->latest_frame.width * 
            visual_data->latest_frame.height * 
            visual_data->latest_frame.channels);
        
        if (annotated_image) {
            // 复制原始图像数据
            memcpy(annotated_image, visual_data->latest_frame.data, 
                visual_data->latest_frame.width * 
                visual_data->latest_frame.height * 
                visual_data->latest_frame.channels);
            
            // 添加标注
            annotate_image(annotated_image, 
                visual_data->latest_frame.width,
                visual_data->latest_frame.height,
                visual_data->latest_frame.channels,
                sensor_data, timestamp);
            
            // 生成文件名：cam400w+当前系统时间
            snprintf(filename, sizeof(filename), "%s/cam400w_%s.jpg", 
                picture_dir, time_str);
            
            // 保存图像
#ifdef HAVE_OPENCV
            bool save_success = opencv_save_image(
                annotated_image,
                visual_data->latest_frame.width,
                visual_data->latest_frame.height,
                visual_data->latest_frame.channels,
                filename, 95);  // 使用较高的质量
            
            if (save_success) {
                log_message(LOG_LEVEL_INFO, "已保存400W摄像头图像: %s", filename);
                success_count++;
            } else {
                log_message(LOG_LEVEL_ERROR, "保存400W摄像头图像失败: %s", filename);
            }
#else
            log_message(LOG_LEVEL_ERROR, "未启用OpenCV支持，无法保存图像");
#endif
            
            // 释放内存
            free(annotated_image);
        }
    }
    
    // 保存左侧800W摄像头图像
    if (stereo_data && stereo_data->left_frame.data) {
        // 复制图像数据用于添加标注
        unsigned char *annotated_image = (unsigned char*)malloc(
            stereo_data->left_frame.width * 
            stereo_data->left_frame.height * 
            stereo_data->left_frame.channels);
        
        if (annotated_image) {
            // 复制原始图像数据
            memcpy(annotated_image, stereo_data->left_frame.data, 
                stereo_data->left_frame.width * 
                stereo_data->left_frame.height * 
                stereo_data->left_frame.channels);
            
            // 添加标注
            annotate_image(annotated_image, 
                stereo_data->left_frame.width,
                stereo_data->left_frame.height,
                stereo_data->left_frame.channels,
                sensor_data, timestamp);
            
            // 生成文件名：cam800w_left+当前系统时间
            snprintf(filename, sizeof(filename), "%s/cam800w_left_%s.jpg", 
                picture_dir, time_str);
            
            // 保存图像
#ifdef HAVE_OPENCV
            bool save_success = opencv_save_image(
                annotated_image,
                stereo_data->left_frame.width,
                stereo_data->left_frame.height,
                stereo_data->left_frame.channels,
                filename, 95);  // 使用较高的质量
            
            if (save_success) {
                log_message(LOG_LEVEL_INFO, "已保存左侧800W摄像头图像: %s", filename);
                success_count++;
            } else {
                log_message(LOG_LEVEL_ERROR, "保存左侧800W摄像头图像失败: %s", filename);
            }
#else
            log_message(LOG_LEVEL_ERROR, "未启用OpenCV支持，无法保存图像");
#endif
            
            // 释放内存
            free(annotated_image);
        }
    }
    
    // 保存右侧800W摄像头图像
    if (stereo_data && stereo_data->right_frame.data) {
        // 复制图像数据用于添加标注
        unsigned char *annotated_image = (unsigned char*)malloc(
            stereo_data->right_frame.width * 
            stereo_data->right_frame.height * 
            stereo_data->right_frame.channels);
        
        if (annotated_image) {
            // 复制原始图像数据
            memcpy(annotated_image, stereo_data->right_frame.data, 
                stereo_data->right_frame.width * 
                stereo_data->right_frame.height * 
                stereo_data->right_frame.channels);
            
            // 添加标注
            annotate_image(annotated_image, 
                stereo_data->right_frame.width,
                stereo_data->right_frame.height,
                stereo_data->right_frame.channels,
                sensor_data, timestamp);
            
            // 生成文件名：cam800w_right+当前系统时间
            snprintf(filename, sizeof(filename), "%s/cam800w_right_%s.jpg", 
                picture_dir, time_str);
            
            // 保存图像
#ifdef HAVE_OPENCV
            bool save_success = opencv_save_image(
                annotated_image,
                stereo_data->right_frame.width,
                stereo_data->right_frame.height,
                stereo_data->right_frame.channels,
                filename, 95);  // 使用较高的质量
            
            if (save_success) {
                log_message(LOG_LEVEL_INFO, "已保存右侧800W摄像头图像: %s", filename);
                success_count++;
            } else {
                log_message(LOG_LEVEL_ERROR, "保存右侧800W摄像头图像失败: %s", filename);
            }
#else
            log_message(LOG_LEVEL_ERROR, "未启用OpenCV支持，无法保存图像");
#endif
            
            // 释放内存
            free(annotated_image);
        }
    }
    
    return (success_count > 0) ? 0 : -1;
} 